<template>
  <q-layout>
    <div class="row justify-center">
      <div class="column justify-center" style="position:absolute;z-index:9999;top:30%;width:300px;">
        <div style="text-align:center;color:#fff;font-weight:bold;font-size: 22px;">{{$t('page.welcome')}}</div>
        <div>
          <q-input dark type="text" v-model="form.username" :float-label="$t('page.username')" clearable :error="$v.form.username.$error" :before="[{icon: 'account_circle'}]" />
          <q-input dark type="password" v-model="form.password" :float-label="$t('page.password')" clearable :error="$v.form.password.$error" :before="[{icon: 'vpn_key'}]" />
        </div>
        <div class="row justify-around q-mt-md">
          <q-btn color="primary" :loading="loading" @click="submit">
            {{$t('page.login')}}
            <span dark slot="loading">
              <q-spinner-hourglass class="on-left" /> {{$t('page.loading')}}...
            </span>
          </q-btn>
          <q-btn color="negative" @click="clear">{{$t('label.clear')}}</q-btn>
        </div>
      </div>
    </div>
    <div id="canvasFloat"></div>
    <script id="vs" type="x-shader/x-vertex">
          varying vec2 vUv;
          void main() {
            vUv = uv;
            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
          }
        </script>
    <script id="fs" type="x-shader/x-fragment">
          uniform sampler2D map;
          uniform vec3 fogColor;
          uniform float fogNear;
          uniform float fogFar;
          varying vec2 vUv;
          void main() {
            float depth = gl_FragCoord.z / gl_FragCoord.w;
            float fogFactor = smoothstep( fogNear, fogFar, depth );
            gl_FragColor = texture2D( map, vUv );
            gl_FragColor.w *= pow( gl_FragCoord.z, 20.0 );
            gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
          }
        </script>
  </q-layout>
</template>

<script>
import {Detector} from 'plugins/Detector.js'
import * as THREE from 'three'
import { required } from 'vuelidate/lib/validators'
import { resetForm } from 'plugins/utils.js'
let container, camera, scene, renderer, mesh, geometry, material
let mouseX = 0
let mouseY = 0
let startTime = Date.now()
let windowHalfX = window.innerWidth / 2
let windowHalfY = window.innerHeight / 2

export default {
  name: 'login',
  data: function () {
    return this.$store.state.auth
  },
  validations: {
    form: {
      username: { required },
      password: { required }
    }
  },
  mounted: function () {
    if (this.$q.localStorage.get.item('admin-token')) {
      this.$router.push('/')
    }
    if (!Detector.webgl) Detector.addGetWebGLMessage()
    this.init()
  },
  methods: {
    init () {
      container = document.getElementById('canvasFloat')
      var canvas = document.createElement('canvas')
      canvas.width = 32
      canvas.height = window.innerHeight
      var context = canvas.getContext('2d')
      var gradient = context.createLinearGradient(0, 0, 0, canvas.height)
      gradient.addColorStop(0, '#1e4877')
      gradient.addColorStop(0.5, '#4584b4')
      context.fillStyle = gradient
      context.fillRect(0, 0, canvas.width, canvas.height)
      container.style.background = 'url(' + canvas.toDataURL('image/png') + ')'
      container.style.backgroundSize = '32px 100%'
      camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 3000)
      camera.position.z = 6000
      scene = new THREE.Scene()
      geometry = new THREE.Geometry()
      var texture = THREE.ImageUtils.loadTexture('statics/cloud10.png', null, this.animate)
      texture.magFilter = THREE.LinearMipMapLinearFilter
      texture.minFilter = THREE.LinearMipMapLinearFilter
      var fog = new THREE.Fog(0x4584b4, -100, 3000)
      material = new THREE.ShaderMaterial({
        uniforms: {
          'map': {type: 't', value: texture},
          'fogColor': {type: 'c', value: fog.color},
          'fogNear': {type: 'f', value: fog.near},
          'fogFar': {type: 'f', value: fog.far}
        },
        vertexShader: document.getElementById('vs').textContent,
        fragmentShader: document.getElementById('fs').textContent,
        depthWrite: false,
        depthTest: false,
        transparent: true
      })
      var plane = new THREE.Mesh(new THREE.PlaneGeometry(64, 64))
      for (var i = 0; i < 8000; i++) {
        plane.position.x = Math.random() * 1000 - 500
        plane.position.y = -Math.random() * Math.random() * 200 - 15
        plane.position.z = i
        plane.rotation.z = Math.random() * Math.PI
        plane.scale.x = plane.scale.y = Math.random() * Math.random() * 1.5 + 0.5
        THREE.GeometryUtils.merge(geometry, plane)
      }
      mesh = new THREE.Mesh(geometry, material)
      scene.add(mesh)
      mesh = new THREE.Mesh(geometry, material)
      mesh.position.z = -8000
      scene.add(mesh)
      renderer = new THREE.WebGLRenderer({antialias: false})
      renderer.setSize(window.innerWidth, window.innerHeight - 4)
      container.appendChild(renderer.domElement)
      document.addEventListener('mousemove', this.onDocumentMouseMove, false)
      window.addEventListener('resize', this.onWindowResize, false)
    },
    onDocumentMouseMove (event) {
      mouseX = (event.clientX - windowHalfX) * 0.25
      mouseY = (event.clientY - windowHalfY) * 0.15
    },
    onWindowResize (event) {
      camera.aspect = window.innerWidth / window.innerHeight
      camera.updateProjectionMatrix()
      renderer.setSize(window.innerWidth, window.innerHeight)
    },
    animate () {
      requestAnimationFrame(this.animate)
      let position = ((Date.now() - startTime) * 0.03) % 8000
      camera.position.x += (mouseX - camera.position.x) * 0.01
      camera.position.y += (-mouseY - camera.position.y) * 0.01
      camera.position.z = -position + 8000
      renderer.render(scene, camera)
    },
    submit () {
      this.$v.form.$touch()

      if (this.$v.form.$error) {
        this.$q.notify(this.$t('page.LoginEmpty'))
        return
      }
      this.loading = true
      this.$store.dispatch('auth/login')
    },
    clear () {
      this.$v.form.$reset()
      resetForm(this.form)
    }
  }
}
</script>

<style>
</style>
